#include "camerawindow.h"

//定义大于指定数量时删除图片
#define MAX_IMAGE_COUNT 10
#define Photo "{#002P2150T1500!#001P2100T1500!#000P2165T1500!#003P1500T1500!}"

CameraWindow::CameraWindow(QWidget *parent)
    : QMainWindow(parent)
{
    // 初始化秒表并启动计时
    timer = new QTimer(this);
    time = new QTime(0, 0, 0);
    timerLabel = new QLabel("00:00:00.000", this);
    totalMilliseconds = 0;
    connect(timer, &QTimer::timeout, this, &CameraWindow::updateTimerDisplay);
    time->start();

    setupUI();
    initCamera();

    //初始化到拍照位置
    MyArm->sendCommand(Photo, "移动到拍照位置");
}

CameraWindow::~CameraWindow()
{
    camera->stop();
    delete camera;
    delete viewfinder;
    delete imageCapture;
    delete contentWidget;
    delete ticTacToe;
    delete MyArm;
    delete timer;
    delete time;
}

void CameraWindow::setupUI() {
    // 1. 整体样式表 (QMainWindow 和 QWidget 的通用设置)
    QString mainStyle = R"(
        QMainWindow, QWidget {
            background-color: #ecf0f1; /* 浅灰色背景 */
            font-family: "Microsoft YaHei", "Arial", sans-serif; /* 优先使用微软雅黑 */
            color: #333333;            /* 深灰色文字 */
        }

        /* QLabel 通用样式 */
        QLabel {
            color: #34495e;         /* 深蓝色文字 */
        }

        /* QPushButton 通用样式 */
        QPushButton {
            background-color: #3498db; /* 蓝色按钮 */
            color: white;
            border: none;
            border-radius: 8px;       /* 圆角 */
            padding: 12px 24px;
            font-size: 16px;
            font-weight: bold;       /* 加粗 */
        }
        QPushButton:hover {
            background-color: #2980b9; /* 悬停时更深的蓝色 */
        }
        QPushButton:pressed {
            background-color: #21618c;   /* 按下时更深的蓝色 */
        }
        QPushButton:disabled {
            background-color: #bdc3c7; /* 不可点击时的灰色 */
            color: #95a5a6;             /* 不可点击时的文字颜色 */
        }

        /* timerLabel 样式 */
        #timerLabel {
            font-size: 28px;
            font-weight: bold;
            color: #e74c3c; /* 红色 */
        }

        /* capturedImageLabel 样式 */
        #capturedImageLabel {
            border: 2px dashed #bdc3c7; /* 虚线边框 */
            padding: 10px;
            color: #7f8c8d;
            font-style: italic;
        }
    )";
    setStyleSheet(mainStyle);  // 应用全局样式

    // 2. 主窗口设置
    setMinimumSize(1024, 768); //调整窗口大小
    setWindowTitle("AI 对战井字棋");
    setWindowIcon(QIcon(":/1.png"));

    // 3. 中心部件和布局 (水平布局)
    QWidget *centralWidget = new QWidget(this);
    QHBoxLayout *mainLayout = new QHBoxLayout(centralWidget); //改为水平布局
    mainLayout->setSpacing(20);             // 增加间距
    mainLayout->setContentsMargins(20, 20, 20, 20); // 增加边距

    // 4. 左侧容器 (包含摄像头、按钮等)
    QWidget *leftContainer = new QWidget(this);
    QVBoxLayout *leftLayout = new QVBoxLayout(leftContainer);
    leftLayout->setSpacing(15);

    // 5. 摄像头预览区域
    viewfinder = new QCameraViewfinder(this);
    viewfinder->setMinimumSize(640, 480);
    viewfinder->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    leftLayout->addWidget(viewfinder);

    // 6. 秒表显示
    timerLabel = new QLabel("00:00:00.000", this);
    timerLabel->setObjectName("timerLabel"); // 设置对象名，用于样式表
    timerLabel->setAlignment(Qt::AlignCenter);
    leftLayout->addWidget(timerLabel);

    // 7. 按钮组 (水平布局)
    QHBoxLayout *buttonLayout = new QHBoxLayout();
    buttonLayout->setSpacing(15);

    playButton = new QPushButton("开始游戏", this);
    captureButton = new QPushButton("我下好了", this);
    captureButton->setEnabled(false);

    buttonLayout->addWidget(playButton);
    buttonLayout->addWidget(captureButton);
    leftLayout->addLayout(buttonLayout);

    // 8. 捕获图片显示区域
    capturedImageLabel = new QLabel("拍摄的图片将显示在这里", this);
    capturedImageLabel->setObjectName("capturedImageLabel"); // 设置对象名
    capturedImageLabel->setAlignment(Qt::AlignCenter);
    capturedImageLabel->setMinimumSize(320, 240);

    leftLayout->addWidget(capturedImageLabel);

    // 9. 右侧容器 (ContentWidget 和 TicTacToe)
     QWidget* rightContainer = new QWidget(this);
     QVBoxLayout* rightLayout = new QVBoxLayout(rightContainer);
     rightLayout->setSpacing(15);

    // 10. ContentWidget 和 TicTacToe
    contentWidget = new ContentWidget(this);
    contentWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
    rightLayout->addWidget(contentWidget);


    ticTacToe = new TicTacToe(this);
    ticTacToe->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
    rightLayout->addWidget(ticTacToe);


    //Yuj添加MyArm
    MyArm = new Widget(this);

    // 11. 将左右容器添加到主布局
    mainLayout->addWidget(leftContainer);
    mainLayout->addWidget(rightContainer);
    mainLayout->setStretch(0,2); //左边占2/3
    mainLayout->setStretch(1,1); //右边占1/3


    setCentralWidget(centralWidget);

     // 创建保存目录和连接信号与槽（保持原样）
    QDir dir(savePath);
    if (!dir.exists()) {
        if (dir.mkpath(".")) {
            qDebug() << "成功创建保存路径：" << savePath;
        } else {
            qDebug() << "无法创建保存路径：" << savePath;
        }
    }
    connect(captureButton, &QPushButton::clicked, this, &CameraWindow::captureImage);
    connect(playButton, &QPushButton::clicked, this, &CameraWindow::playGame);
}

void CameraWindow::initCamera()
{
    // 获取所有可用摄像头
    QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
    if (QCameraInfo::availableCameras().isEmpty()) {
        qDebug() << "没有检测到摄像头！";
        return;
    }

    //选择0为选择第1个摄像头，即默认的摄像头
    QCameraInfo selectedCameraInfo = cameras.at(1);
    camera = new QCamera(selectedCameraInfo, this);
    imageCapture = new QCameraImageCapture(camera);

    camera->setViewfinder(viewfinder);
    camera->start();

    // 设置图片捕获参数
    imageCapture->setCaptureDestination(QCameraImageCapture::CaptureToFile);

    connect(imageCapture, &QCameraImageCapture::imageCaptured,
            this, &CameraWindow::onImageCaptured);
    connect(imageCapture, &QCameraImageCapture::imageSaved,
            this, &CameraWindow::onImageSaved);
}
void CameraWindow::captureImage()
{
    FLAG_0_SendImg_OK = 0;
    if (imageCapture->isReadyForCapture()) {
        QString fileName = savePath + QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss") + ".jpg";
        qDebug() << "尝试保存图片到：" << fileName;
        imageCapture->capture(fileName);

        // 检查大于10张图片时，删除最旧的图片
        QDir dir(savePath);
        if (dir.exists()) {
            QStringList nameFilters;
            nameFilters << "*.jpg"; // 假设图片格式为jpg
            QFileInfoList fileList = dir.entryInfoList(nameFilters, QDir::Files, QDir::Time);

            if (fileList.size() > MAX_IMAGE_COUNT) {
                for (int i = 0; i < fileList.size() - MAX_IMAGE_COUNT; ++i) {
                    QFile::remove(fileList.at(i).filePath());
                    qDebug() << "删除图片：" << fileList.at(i).filePath();
                }
            }
        }
    }
}

void CameraWindow::onImageCaptured(int id, const QImage &preview)
{
    Q_UNUSED(id);
    QPixmap pixmap = QPixmap::fromImage(preview);
    capturedImageLabel->setPixmap(pixmap.scaled(capturedImageLabel->size(),
                                      Qt::KeepAspectRatio,
                                      Qt::SmoothTransformation));
}

void CameraWindow::onImageSaved(int id, const QString &path)
{
    Q_UNUSED(id);
    qDebug() << "图片已保存到：" << path;

    // 上传图片到 ContentWidget 进行处理
    contentWidget->on_uploadImageButton_clicked(path);

    // 暂停计时
    stopTimer();
    //AI下棋
    captureButton->setText("AI下棋中");
    captureButton->setEnabled(false);
    FLAG_0_SendImg_OK = 1;
}
void CameraWindow::updateTimerDisplay()
{
    // 计算总时间 = 累计时间 + 当前时段的时间
    qint64 currentElapsed = time->elapsed();
    qint64 total = totalMilliseconds + currentElapsed;

    // 转换为小时、分钟、秒、毫秒
    int hours = total / 3600000;
    int remaining = total % 3600000;
    int minutes = remaining / 60000;
    remaining %= 60000;
    int seconds = remaining / 1000;
    int milliseconds = remaining % 1000;

    // 格式化时间字符串（HH:mm:ss.zzz）
    QString timeStr = QString("%1:%2:%3.%4")
                          .arg(hours, 2, 10, QLatin1Char('0'))
                          .arg(minutes, 2, 10, QLatin1Char('0'))
                          .arg(seconds, 2, 10, QLatin1Char('0'))
                          .arg(milliseconds, 3, 10, QLatin1Char('0'));
    timerLabel->setText(timeStr);
    timeStrText = timeStr;
}
void CameraWindow::stopTimer()
{
    // 暂停计时
    timer->stop();
    totalMilliseconds += time->elapsed(); // 累加当前时段
}
void CameraWindow::startTimer()
{
    // 开始计时
    time->start(); // 重新开始计时
    timer->start(100);     // 每100毫秒更新一次显示（精度根据系统调整）
}
void CameraWindow::gameing()
{
    QVector<QVector<int>> currentBoard = {
        {0, 0, 0},
        {0, 0, 0},
        {0, 0, 0}
    };

    int GameCount = ticTacToe->getGameCount();
    int waitCount = 0;

    while(ticTacToe->getGameCount() == GameCount)
    {
        if (ticTacToe->getplayerTurn()) 
        {
            // 等待图片上传完成
            while (!FLAG_0_SendImg_OK) {
                QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
            }

            // 等待API返回结果
            while (!contentWidget->FLAG_1_API_BACK_OK) {
                QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
            }

            if (contentWidget->FLAG_1_API_BACK_OK == 2) {
                resetBoard();
                break;
            }

            qDebug() << "API返回的文字" << contentWidget->Text;
            ticTacToe->parseResponseToBoardState_byAPI(contentWidget->Text);
            //3、接收抽象棋盘，第一次时，上次棋盘初始化为全0
            currentBoard = ticTacToe->printAndGetBoardState();

            //4、传递两个数组给tictactoe，做合法性判断（OK继续）
            int MoveNum = ticTacToe->isPlayerMove(previousBoard, currentBoard);
            //1是正常
            //2是玩家挪棋
            //3是没下棋
            //4是用O棋子
            if (MoveNum == 3)
            {
                waitCount++;
                qDebug()<<waitCount;

                //最多等三次
                if(waitCount == 3)
                {
                    break;
                }
                //打开定时器
                startTimer();
                captureButton->setText("我下好了");
                captureButton->setEnabled(true);
                FLAG_0_SendImg_OK = 0;
                continue;
            }
            else if(MoveNum != 1)
            {
                ErrorFunc(MoveNum);
                resetBoard();
                break;
            }
            //5、更新UI
            ticTacToe->updateBoard(currentBoard);
        }
        else
        {
            //6、传递x,y,寻找最好的落点
            int coordinate = ticTacToe->findBestMove(currentBoard);
            if(coordinate == -1)
            {
                WinHappy(0);
                resetBoard();
                break;
            }
            //7、等待机械臂下棋完成
            qDebug()<< coordinate/3 <<","<< coordinate%3;
            DoArm(coordinate/3,coordinate%3);
            //8、更新抽象棋局
            currentBoard[coordinate/3][coordinate%3] = 2;
            QTimer::singleShot(6*1500, this, [this,currentBoard]()
            {
                //9、UI，更新上次棋盘
                ticTacToe->updateBoard(currentBoard);
                previousBoard = currentBoard;
                //打开定时器
                startTimer();
                captureButton->setText("我下好了");
                captureButton->setEnabled(true);
                FLAG_0_SendImg_OK = 0;
            });
        }
    }
    WinHappy(ticTacToe->whoWin);
    resetBoard();
}
void CameraWindow::playGame()
{
    captureButton->setEnabled(true);
    playButton->setText("游戏中");
    playButton->setEnabled(false);
    captureButton->setEnabled(true);
    startTimer();
    gameing();
    //stotalMilliseconds = 0;
    captureButton->setEnabled(false);
    playButton->setText("开始游戏");
    playButton->setEnabled(true);
}
void CameraWindow::resetBoard() {
    ticTacToe->resetBoard();
    previousBoard = QVector<QVector<int>>(3, QVector<int>(3, 0));
    captureButton->setText("我下好了");
    captureButton->setEnabled(true);
    stopTimer();
    totalMilliseconds = 0;
    timerLabel->setText("00:00:00.000");
    FLAG_0_SendImg_OK = 0;
}
void CameraWindow::ErrorFunc(int errorCode)
{
    //1是正常
    //2是玩家挪棋
    //3是没下棋
    //4是用O棋子
    switch(errorCode)
    {
        case 2:
            {
                QMessageBox::critical(this, "错误", "玩家挪棋！");
                break;
            }
        case 4:
            {
                //因为平局报错，所以屏蔽
                //QMessageBox::critical(this, "错误", "用O棋子！");
                break;
            }
    }
}
void CameraWindow::DoArm(int x,int y)
{
    int move_time = 1500;
    MyArm->actionGroupGet(0,135,20, move_time);
    QTimer::singleShot(3*move_time, this, [this,x,y,move_time]()
    {
        //去指定坐标完成1.5s完成放置
        MyArm->BYxyPutPro(x,y,move_time);
        // 等待放置完成返回结果
        while (!MyArm->ArmPutFLAG)
            {
                QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
            }
        QTimer::singleShot(move_time, this, [this]()
        {
            MyArm->sendCommand(Photo, "移动到拍照位置");
        });
    });
}
void CameraWindow::WinHappy(int whoWin)
{
    QString Text = "提示";
    if(whoWin == 0)
    {
        Text = "平局,玩家用时:" + timeStrText;
    }
    else if (whoWin == 2) {
        Text = "电脑获胜,玩家用时:" + timeStrText;
    }
    else if (whoWin == 1) {
        Text = "玩家获胜,玩家用时:" + timeStrText;
    }
    QMessageBox::information(this,"提示",Text);
}
